import React from 'react';
import Utils from './utils.js';
import TodoItem from './TodoItem.js';
import TodoFooter from './TodoFooter.js';
const ALL_TODOS = 'all';
const ACTIVE_TODOS = 'active';
const COMPLETED_TODOS = 'completed';	

export default class TodoApp extends React.Component{
	constructor(props){
		super(props);
		this.state = {
			newTodo: '',
			todos: [],
			nowShowing: ALL_TODOS,
			editing: null,
			error: null
		};
		this.handleChange = this.handleChange.bind(this);
		this.handleNewTodoKeyDown = this.handleNewTodoKeyDown.bind(this);
		this.requestURL = this.props.requestBaseURL;
	}
	edit(todo) {
		this.setState({editing: todo.id});
	}
	cancel() {
		this.setState({editing: null});
	}
    setTodo(title) {
		let previousTodos = this.state.todos;
		let newTodo = {
			id: Utils.uuid(),
			title: title,
			completed: false
		};
		let newTodos = previousTodos.concat(newTodo);
		this.setState(
			{
				newTodo: '',
				todos: newTodos
			}
		)
		fetch(this.requestURL, {method: 'POST', 
			headers: {
				"Content-Type": "application/x-www-form-urlencoded",
			},
			body: `id=${newTodo.id}&title=${newTodo.title}&completed=0`,
			credentials: 'include'
		})
		.then(res => res.json())
		.then(
		  (result) => {
			let error = this.hasError(result);
			if(error){
				this.setState({
				error: error
				});
			}
		  },
		  (error) => {
			  this.setState({error: error.message});
		  }
		)		

	};
	hasError(result){
	//check application level error		
		if(result.code < 0)
			return result.msg;		
		return null;
	}
	componentDidMount(){
		// Invoked once the component is mounted to the DOM
		// Good for making AJAX requests
		if(this.requestURL == undefined)
			return;
		fetch(this.requestURL,{credentials: 'include'})
		.then(res => res.json())
		.then(
		  (result) => {
			let error = this.hasError(result);
			if(error){
				this.setState({
			  	error: this.hasError(result)
				});
			}
			else{
				this.setState({
					todos: result.data,
				})
				if(this.props.isLogin === false){
					this.props.makeLogin();
				}
			}
		  },
		  (error) => {
			  this.setState({error: error.message});
		  }
		)		
	  }	
	filter(event) {
		console.log(event.target);
		this.setState({nowShowing: event.target.value});
	}
	handleChange(event){
		this.setState({newTodo: event.target.value});
	}
	handleNewTodoKeyDown(event) {
		if (event.keyCode !== Utils.ENTER_KEY) {
			return;
		}
		event.preventDefault();

		var val = this.state.newTodo.trim();

		if (val) {
			this.setTodo(val);
		}
	}
	destroy(todo) {
		let previousTodos = this.state.todos;
		let newTodos = previousTodos.filter(function (candidate) {
			return candidate !== todo;
		});		
		this.setState({todos: newTodos});
		fetch(this.requestURL, {method: 'POST', 
			headers: {
				"Content-Type": "application/x-www-form-urlencoded",
			},
			body: `id=${todo.id}&delete=1`,
			credentials: 'include'
		})
		.then(res => res.json())
		.then(
		  (result) => {
			let error = this.hasError(result);
			if(error){
				this.setState({
				error: error
				});
			}
		  },
		  (error) => {
			  this.setState({error: error.message});
		  }
		)		
	}
	toggle(todo) {
		let previousTodos = this.state.todos;
		let newTodos = previousTodos.map(function (candidate) {
			if(todo !== candidate)
				return candidate;
			else{				
				let new_candidate = {
					id: candidate.id,
					title: candidate.title,
					completed: !candidate.completed
				};				
				return new_candidate;
			}
		});		
		this.setState({todos: newTodos});
		let completed = (todo.completed ? 0 : 1);
		fetch(this.requestURL, {method: 'POST', 
			headers: {
				"Content-Type": "application/x-www-form-urlencoded",
			},
			body: `id=${todo.id}&title=${todo.title}&completed=${completed}`,
			credentials: 'include'
		})
		.then(res => res.json())
		.then(
		  (result) => {
			let error = this.hasError(result);
			if(error){
				this.setState({
				error: error
				});
			}
		  },
		  (error) => {
			  this.setState({error: error.message});
		  }
		)		

	}
	save(todo, text){
		let previousTodos = this.state.todos;
		let newTodos = previousTodos.map(function (candidate) {
			if(todo !== candidate)
				return candidate;
			else{				
				let new_candidate = {
					id: candidate.id,
					title: text,
					completed: candidate.completed
				};				
				return new_candidate;
			}
		});		
		this.setState({todos: newTodos});	
		this.setState({editing: null});	
		fetch(this.requestURL, {method: 'POST', 
			headers: {
				"Content-Type": "application/x-www-form-urlencoded",
			},
			body: `id=${todo.id}&title=${text}&completed=${todo.completed}`,
			credentials: 'include'
		})
		.then(res => res.json())
		.then(
		  (result) => {
			let error = this.hasError(result);
			if(error){
				this.setState({
				error: error
				});
			}
		  },
		  (error) => {
			  this.setState({error: error.message});
		  }
		)		

	}
	render(){
		let todos = this.state.todos;

		let shownTodos = todos.filter((todo) => {
			switch (this.state.nowShowing) {
				case ACTIVE_TODOS:
					return !todo.completed;
				case COMPLETED_TODOS:
					return todo.completed;
				default:
					return true;
			}
		}, this);
		let todoItems = shownTodos.map((todo) => {
			return (
				<TodoItem 
					key={todo.id}
					todo={todo}
					onDestroy = {this.destroy.bind(this, todo)}
					onToggle = {this.toggle.bind(this, todo)}
					onSave = {this.save.bind(this, todo)}
					onEdit = {this.edit.bind(this, todo)}
					editing={this.state.editing === todo.id}
					onCancel = {this.cancel.bind(this)}
				/>
			);
		}, this);
		let main = null;
		if(todos.length > 0){
		    main = (
				<section className="main">
				<ul className="todo-list"> 
					{todoItems}
				</ul>
			    </section>
			);
		}
		let footer = null;
		footer = <TodoFooter
			nowShowing={this.state.nowShowing}
			filter={(e) => this.filter(e)}
			/>
		let error = null;
		if(this.state.error){
			error = <div> Error: {this.state.error}</div>
		}
		return (
				<div>
					<header className="header">
						<div className="todotitle">todos</div>
						{error}
						<input
							className="new-todo"
							placeholder="What needs to be done?"
							value={this.state.newTodo}
							onKeyDown={this.handleNewTodoKeyDown}
							onChange={this.handleChange}
							autoFocus={true}
						/>
					</header>
					{main}
					{footer}
				</div>
		);
						
	}

}
